package com.epam;

public class FloydWarshall {

	private int numVertex;
	private int[][] mtx;
	
	private int[][] solvedMin;
	private int[][] solvedMax;
	
	private static final int INFINITY = 99999999;
	
	public FloydWarshall(int[][] matrix){
		numVertex = matrix.length;
		
		this.mtx = matrix;
		
		solvedMin = new int[numVertex][numVertex];
		solvedMax = new int[numVertex][numVertex];
		
		for(int i = 0; i < numVertex; i++){
			for(int j = 0; j < numVertex; j++) {
				solvedMin[i][j] = mtx[i][j] != 0 ?  mtx[i][j] : INFINITY;
				solvedMax[i][j] = mtx[i][j] != 0 ? -mtx[i][j] : INFINITY;
			}
		}
	}
	
	public void solve(){
		for (int k = 0; k < numVertex; k++) {
            for (int i = 0; i < numVertex; i++) {
                for (int j = 0; j < numVertex; j++) {                
                	solvedMin[i][j] = Math.min(solvedMin[i][j], solvedMin[i][k] + solvedMin[k][j]);
                	solvedMax[i][j] = Math.min(solvedMax[i][j], solvedMax[i][k] + solvedMax[k][j]);
                }
            }
        }
	}
	
	public String sayMinDistance(int from, int to){
		if( from < 0 || from >= numVertex ||
			to 	 < 0 || to   >= numVertex)
						throw new IllegalArgumentException();
			
		return solvedMin[from][to] == INFINITY ? 
				String.format("Vertex %d is unreachable from %d.", to, from) :
				String.format("Min distance from %d to %d is %d.", from, to, solvedMin[from][to]);
	}
	
	public String sayMaxDistance(int from, int to){
		if( from < 0 || from >= numVertex ||
			to 	 < 0 || to   >= numVertex)
						throw new IllegalArgumentException();
			
		return solvedMax[from][to] == INFINITY ? 
				String.format("Vertex %d is unreachable from %d.", to, from) :
				String.format("Max distance from %d to %d is %d.", from, to, -solvedMax[from][to]);
	}
	
	public static void main(String[] args) {
		int[][] amx = { {0,8,0,0,8},
						{0,0,0,3,0},
						{0,0,0,0,0},
						{0,0,0,0,8},
						{0,0,0,0,0}
			};
		
		FloydWarshall fw = new FloydWarshall(amx);
		fw.solve();
		
		System.out.println(fw.sayMaxDistance(0, 4));
		System.out.println(fw.sayMinDistance(0, 4));

		
		System.out.println(fw.sayMinDistance(3, 2));
	}

}
